using System;
using System.Linq;
using LambdaGp.Core;

namespace LambdaGp.Operators.Terminals
{
    public class Variable : Terminal
    {
        public Variable(string name, double defaultValue)
            : base(name)
        {
            DefaultValue = defaultValue;
        }

        public double DefaultValue { get; set; }

        public static VariableInstance GetVariable(Individual individual, string name)
        {
            return
                individual
                    .Storage
                    .OfType<VariableInstance>()
                    .Single(vi => vi.Variable.Name == name);
        }
        
        public override Func<double> CompileToFunc(Individual individual, OperatorNode operatorNode)
        {
            VariableInstance vinst = GetVariable(individual);
            return () => vinst.Value;
        }

        public override void AddToStorage(Individual individual)
        {
            individual.Storage.Add(new VariableInstance(this));
        }
        
        public VariableInstance GetVariable(Individual individual)
        {
            return GetVariable(individual, Name);
        }        
    }
}
